Code
import pandas as pd
import osmnx as ox
from matplotlib import pyplot as plt
import geopandas as gpd
import altair as alt
import pygrisThis analysis looks at the number of amenities located within the flood hazard area in the city of Philadelphia. Amenity data is downloaded from Open Street Maps, and I also determine the planning district that each amenity is located in. I present the results using interactive maps created using the geopandas explore() function and charts created using the altair package.
I import the packages I will use for this analysis. I used osmnx to download data from Open Street Maps. Pandas and geopandas are used to manipulate and transform my data. Altair and matplotlib are used to create visualizations.
import pandas as pd
import osmnx as ox
from matplotlib import pyplot as plt
import geopandas as gpd
import altair as alt
import pygrisimport warnings
warnings.filterwarnings('ignore')pd.set_option('display.max_columns', None)I download amenity data from Open Street Maps for all of Philadelphia. I try to focus on key public amenities that would be problematic to have in a flood hazard area and could be damaged durring a flood. The OSM amenity data is projected into an apporporiate cordinate system. I then count the number of each amenity type located in Philadelphia.
amenities = ox.features_from_place("Philadelphia, PA", tags={"amenity": ["bar","place_of_worship","restaurant",\
"school","fast_food","cafe","bank","fuel" \
"bar","pub","library","post_office","fire_station",\
"community_centre","kindergarten","theatre" \
"hospital","police","cinema"]})amenities = amenities.to_crs(6565) The chart below was created using matplotlib and shows the total number of each type of amenity in Philadelphia based on OSM data.
fig, ax = plt.subplots(figsize=(5, 2.5))
groups = amenities.groupby('amenity')[['amenity']].count().rename({'amenity':'count'},axis=1)
groups = groups.sort_values('count',ascending=False)
plt.bar(height=groups['count'],x=groups.index)
plt.xticks(rotation = 90)
plt.title('Number of Amenities in Philadelphia based on OSM data')Text(0.5, 1.0, 'Number of Amenities in Philadelphia based on OSM data')

Next, I get the flood hazard boundary data from the city’s open data portal. The 100 year and 500 year flood plain are included as seperate layers. I perform some cleaning operations to both layers and then concatenate them together using the concat function in pandas.
flood_plain_100_year = gpd.read_file('https://opendata.arcgis.com/datasets/1d6d353ab50b4884b586c05ee2a661db_0.geojson').to_crs(6565)
flood_plain_500_year = gpd.read_file('https://opendata.arcgis.com/datasets/1e6f6315225544c88549478d25cc5181_0.geojson').to_crs(6565)flood_plain_100_year.loc[flood_plain_100_year['FLOODWAY'] == 'FLOODWAY', ['ZONE']] = 'FLOODWAY'
flood_plain_100_year = flood_plain_100_year[['geometry','ZONE']].fillna('100 YEAR')flood_plain_500_year['ZONE'] = '500 YEAR'
flood_plain_500_year = flood_plain_500_year[['geometry','ZONE']]flood_plain = pd.concat([flood_plain_100_year,flood_plain_500_year])The interactive map below shows where the flood hazard areas are located in Philadelphia.
flood_plain.explore(column='ZONE',tiles='CartoDB positron',cmap='winter',style_kwds ={'stroke':False})